<script setup lang="ts">
import { useMemberStore } from '@/stores/modules/memberStore';
import { onLoad, onShow } from '@dcloudio/uni-app';
import BlankCart from '@/static/images/blank_cart.png';
import { CartItem } from '@/types/cart';
import { ref } from 'vue';
import { getCartAPI, deleteCartAPI, putCartBySkuIdAPI, putAllCartSelectedAPI } from '@/apis/cart';
import { useXtxRecommand } from '@/composables/useXtxRecommand';
import { InputNumberBoxEvent } from '@/types/vk-data-input-number-box';

const { safeAreaInsets } = uni.getSystemInfoSync();

// 获取当前页面栈
const pageStack = getCurrentPages();

const memberStore = useMemberStore();

const { xtxRecommandRef, xtxRecommandLoadMore, xtxRecommandRefresh } = useXtxRecommand();

// 是否处于加载中
const loading = ref(false);

// 获取购物车商品列表
const cartList = ref<CartItem[]>([]);
const getCartList = async () => {
  try {
    loading.value = true;
    const response = await getCartAPI().request;
    cartList.value = response.result;
  }
  catch {
    uni.showToast({ icon: 'none', title: '当前网络状态不佳，请稍后重试！' });
  }
  finally {
    loading.value = false;
  }
};

// 删除购物车商品项
const onCartDelete = (skuId: string) => {
  if (!loading.value) {
    uni.showModal({
      content: '是否将此件商品移出购物车？',
      success: async () => {
        await deleteCartAPI({ ids: [skuId] }).request;
        await getCartList();
        uni.showToast({ icon: 'success', title: '移出成功！' });
      },
    });
  }
};

// 请求定时器
let countTimer: number | null;

// 修改购物车商品数量事件
const onCartCountChange = (e: InputNumberBoxEvent) => {
  // 节流策略
  if (countTimer) clearTimeout(countTimer);
  countTimer = setTimeout(async () => {
    try {
      // 修改商品数量
      loading.value = true;
      const { value, index } = e;
      await putCartBySkuIdAPI(index, { count: value }).request;
    }
    catch {
      getCartList();
    }
    finally {
      loading.value = false;
    }
  }, 500);
};

// 购物车商品选中变化事件
const onSelectedChange = async (type: 'single' | 'all', payload: { id?: string, selected: boolean }) => {
  if (loading.value) return uni.showToast({ icon: 'none', title: '忙不过来了，客官请稍后再试！' });
  try {
    loading.value = true;
    const { id, selected } = payload;
    if (type === 'single') {
      // 单选改变
      await putCartBySkuIdAPI(id!, { selected }).request;
      cartList.value.find(i => i.skuId === id!)!.selected = selected;
    } else if (type === 'all') {
      // 全选改变
      await putAllCartSelectedAPI(selected).request;
      cartList.value.forEach(i => i.selected = selected);
    }
  }
  catch {
    getCartList();
  }
  finally {
    loading.value = false;
  }
};

// 结算事件
const onPay = () => {
  if (!cartList.value.find(i => i.selected)) return uni.showToast({ icon: 'none', title: '请选择需要结算的商品！' });
  // 跳转到结算页
  uni.navigateTo({ url: '/pagesOrder/create/create' });
};

// 是否处于刷新状态
const refreshing = ref(false);

// 刷新事件
const onRefresh = async () => {
  refreshing.value = true;
  await Promise.all([getCartList(), xtxRecommandRefresh()]);
  refreshing.value = false;
};

onShow(() => {
  if (memberStore.profile) getCartList();
});

onLoad(() => {
  if (!memberStore.profile) uni.navigateTo({ url: '/pages/login/login' });
});
</script>

<template>
  <scroll-view scroll-y class="scroll-view" refresher-enabled :refresher-triggered="refreshing"
    @refresherrefresh="onRefresh" @scrolltolower="() => xtxRecommandLoadMore()">
    <!-- 已登录 -->
    <template v-if="memberStore.profile">
      <!-- 购物车列表 -->
      <view class="cart-list" v-if="cartList.length">
        <view class="tips">
          <text class="label">满减</text>
          <text class="desc">满1件即可享受9折优惠</text>
        </view>
        <!-- 商品区 -->
        <uni-swipe-action>
          <uni-swipe-action-item v-for="item in cartList" :key="item.skuId">
            <view class="goods">
              <text class="checkbox" :class="{ checked: item.selected }"
                @tap="onSelectedChange('single', { id: item.skuId, selected: !item.selected })" />
              <navigator class="navigator" :url="`/pages/good/good?id=${item.id}`" hover-class="none">
                <image class="picture" :src="item.picture" mode="aspectFill" />
                <view class="meta">
                  <view class="name ellipsis">{{ item.name }}</view>
                  <view class="attrsText ellipsis">{{ item.attrsText }}</view>
                  <view class="price">{{ item.price }}</view>
                </view>
              </navigator>
              <!-- 商品数量 -->
              <view class="count">
                <vk-data-input-number-box v-model="item.count" :min="1" :max="item.stock" :index="item.skuId"
                  :disabled="loading" @change="onCartCountChange" />
              </view>
            </view>
            <!-- 删除 -->
            <template #right>
              <view class="cart-swipe-right">
                <button class="button delete-button" @tap="onCartDelete(item.skuId)">删除</button>
              </view>
            </template>
          </uni-swipe-action-item>
        </uni-swipe-action>
      </view>
      <!-- 无商品状态 -->
      <view class="cart-blank" v-else>
        <image class="image" :src="BlankCart" />
        <text class="text">购物车里空无一物</text>
        <navigator open-type="switchTab" url="/pages/index/index">
          <button class="button">去首页看看</button>
        </navigator>
      </view>
      <!-- 工具栏 -->
      <view class="toolbar" :style="{ paddingBottom: `${pageStack.length === 1 ? 0 : safeAreaInsets?.bottom || 0}px` }">
        <view class="toolbar-container">
          <text class="all" :class="{ checked: cartList.every(i => i.selected) }"
            @tap="onSelectedChange('all', { selected: !cartList.every(i => i.selected) })">全选</text>
          <text class="text">合计：</text>
          <text class="amount">{{ cartList.reduce((pv, cv) => pv + cv.price * cv.count, 0).toFixed(2) }}</text>
          <view class="button-group">
            <view class="button payment-button" :class="{ disabled: !cartList.length }" @tap="onPay">去结算</view>
          </view>
        </view>
      </view>
    </template>
    <!-- 未登录 -->
    <view class="login-blank" v-else>
      <text class="text">登录后查看购物车中的商品</text>
      <navigator url="/pages/login/login" hover-class="none">
        <button class="button">去登录</button>
      </navigator>
    </view>
    <!-- 推荐商品 -->
    <XtxRecommand ref="xtxRecommandRef" />
    <!-- 底部占位空盒子 -->
    <view class="toolbar-height"></view>
  </scroll-view>
</template>

<style lang="scss">
.scroll-view {
  width: 100vw;
  height: 100vh;
  background-color: #f7f7f8;
}

.cart-list {
  padding: 0 20rpx;

  .tips {
    margin: 10rpx;
    display: flex;
    align-items: center;
    font-size: 26rpx;
    line-height: 1.2;
    color: #666;

    .label {
      margin-right: 10rpx;
      background-color: #27ba9b;
      border-radius: 4rpx;
      padding: 7rpx 15rpx 5rpx;
      color: #fff;
      font-size: 24rpx;
    }
  }

  .uni-swipe_box {
    margin-bottom: 20rpx;
  }

  .goods {
    position: relative;
    padding: 15rpx 15rpx 15rpx 80rpx;
    background-color: #fff;
    border-radius: 10rpx;
    overflow: hidden;
    display: flex;

    .navigator {
      display: flex;
    }

    .checkbox {
      position: absolute;
      top: 0;
      left: 0;
      width: 80rpx;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;

      &::before {
        content: '\e6cd';
        color: #444;
        font-size: 40rpx;
        font-family: 'erabbit' !important;
      }

      &.checked::before {
        content: '\e6cc';
        color: #27ba9b;
      }
    }

    .picture {
      width: 180rpx;
      height: 180rpx;
    }

    .meta {
      margin-left: 20rpx;
      flex: 1;
      display: flex;
      flex-direction: column;
      justify-content: space-evenly;
    }

    .name {
      height: 72rpx;
      font-size: 26rpx;
      color: #444;
    }

    .attrsText {
      margin: 10rpx 0;
      line-height: 1.8;
      padding: 0 15rpx;
      font-size: 24rpx;
      align-self: flex-start;
      border-radius: 4rpx;
      color: #888;
      background-color: #f7f7f8;
    }

    .price {
      line-height: 1.8;
      font-size: 26rpx;
      color: #444;
      margin-bottom: 2rpx;
      color: #cf4444;

      &::before {
        content: '￥';
        font-size: 80%;
      }
    }

    // 商品数量
    .count {
      position: absolute;
      bottom: 15rpx;
      right: 5rpx;
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 220rpx;
      height: 36rpx;

      .text {
        height: 100%;
        padding: 0 20rpx;
        font-size: 36rpx;
        line-height: 1;
        color: #444;
      }

      .input {
        height: 100%;
        text-align: center;
        border-radius: 4rpx;
        font-size: 24rpx;
        color: #444;
        background-color: #f6f6f6;
      }
    }
  }

  .cart-swipe {
    display: block;
    margin: 20rpx 0;
  }

  .cart-swipe-right {
    display: flex;
    height: 100%;

    .button {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 50px;
      padding: 6px;
      line-height: 1.5;
      color: #fff;
      font-size: 26rpx;
      border-top-left-radius: 0;
      border-top-right-radius: 10rpx;
      border-bottom-left-radius: 0;
      border-bottom-right-radius: 10rpx;
    }

    .delete-button {
      background-color: #cf4444;
    }
  }
}

// 空状态
.cart-blank,
.login-blank {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  height: 60vh;

  .image {
    width: 400rpx;
    height: 281rpx;
  }

  .text {
    color: #444;
    font-size: 26rpx;
    margin: 20rpx 0;
  }

  .button {
    width: 240rpx !important;
    height: 60rpx;
    line-height: 60rpx;
    margin-top: 20rpx;
    font-size: 26rpx;
    border-radius: 60rpx;
    color: #fff;
    background-color: #27ba9b;
  }
}

// 吸底工具栏
.toolbar {
  position: fixed;
  left: 0;
  bottom: var(--window-bottom);
  z-index: 1;
  width: 100vw;
  border-top: 1rpx solid #ededed;
  border-bottom: 1rpx solid #ededed;
  background-color: #fff;

  .toolbar-container {
    padding: 20rpx;
    display: flex;
    align-items: center;
  }

  .all {
    margin-left: 25rpx;
    font-size: 14px;
    color: #444;
    display: flex;
    align-items: center;
  }

  .all::before {
    font-family: 'erabbit' !important;
    content: '\e6cd';
    font-size: 40rpx;
    margin-right: 8rpx;
  }

  .checked::before {
    content: '\e6cc';
    color: #27ba9b;
  }

  .text {
    margin-right: 8rpx;
    margin-left: 32rpx;
    color: #444;
    font-size: 14px;
  }

  .amount {
    font-size: 20px;
    color: #cf4444;

    .decimal {
      font-size: 12px;
    }

    &::before {
      content: '￥';
      font-size: 12px;
    }
  }

  .button-group {
    margin-left: auto;
    display: flex;
    justify-content: space-between;
    text-align: center;
    line-height: 72rpx;
    font-size: 13px;
    color: #fff;

    .button {
      width: 240rpx;
      margin: 0 10rpx;
      border-radius: 72rpx;
    }

    .payment-button {
      background-color: #27ba9b;

      &.disabled {
        opacity: 0.6;
      }
    }
  }
}

// 底部占位空盒子
.toolbar-height {
  height: 100rpx;
}
</style>
